package com.mlamp.递归;

public class 数值的整数次方 {
    public static void main(String[] args) {
        数值的整数次方 instance = new 数值的整数次方();
        double v = instance.myPow2(0.00001, 2147483647);
        System.out.println(v);
        System.out.println(instance.myPow3(2, 30));
        System.out.println(instance.mypowcore(2, 4));
        System.out.println(instance.mypowB(2, 30));
    }

    public double myPow(double x, int n) {
        if (n >= 0) return myPowSubProcess(x, n);
        else {
            int tmp = -n;
            double v = myPowSubProcess(x, tmp);
            return 1 / v;
        }
    }

    public double myPow31(double x, int n) {
        if (x == 0) return 0;
        long b = n;
        double res = 1.0;
        if (b < 0) {
            x = 1 / x;
            b = -b;
        }
        while (b > 0) {
            if ((b & 1) == 1) {
                res *= x;
            }
            x *= x;
            b = b >> 1;
        }
        return res;
    }


    public double myPow2(double x, int n) {
        if (x == 0) return 0;
        long b = n;
        double res = 1.0;
        if (b < 0) {
            x = 1 / x;
            b = -b;
        }
        while (b > 0) {
            if ((b & 1) == 1) {
                res *= x;//当二进制的位数为1，则需要进行相乘
            }
            x *= x;//大括号进行res*=x是在if判断语句之外，不然当遇到0的位数后，没有b>>1的操作，会陷入死循环
            b = b >> 1;
        }
        return res;
    }


    public double mypow4(double x, int n) {
        if (x == 0) return 0;
        long b = n;
        double res = 1.0d;
        if (b < 0) {
            x = 1 / x;
            b = -b;
        }

        while (b > 0) {
            if ((b & 1) == 1) {
                res *= x;
            }
            x *= x;
            b = b >> 1;
        }
        return res;
    }


    public double mypowB(double x, int n){
        if(x == 0) return 0;
        double res = 1.0d;
        if (n < 0){
            n = -n;
            x = 1/x;
        }
        while (n > 0){
            if ((n & 1) == 1){
                res *= x;
            }
            x *= x;
            n = n >> 1;
        }
        return res;
    }



    public double mypowA(double x, int n) {
        if (x == 0) return 0;
        double res = 1.0d;
        if (n < 0) {
            x = 1 / x;
            n = -n;
        }
        while (n > 0) {
            if ((n & 1) == 1) {
                res *= x;
            }
            x *= x;
            n = n >> 1;
        }
        return res;
    }


    public double myPow3(double x, int n) {
        if (x == 0) return 0;
        long b = n;
        double res = 1.0d;
        if (b < 0) {
            x = 1 / x;
            b = -b;
        }
        while (b > 0) {
            if ((b & 1) == 1) {
                res *= x;
            }
            x *= x;
            b = b >> 1;
        }
        return res;
    }


    public double myPowSubProcess(double x, int n) {
        if (n == 1) return x;
        if (n == 0) return 1;
        int floor = (int) Math.floor(n / 2);
        return myPow(x, floor) * myPow(x, n - floor);
    }


    public double mypow(double x, int n) {
        if (n < 0) {
            x = 1 / x;
            n = -n;
        }
        return mypowcore(x, n);
    }

    public double mypowcore(double x, int n) {
        if (n == 1) return x;
        if (n == 0) return 1;
        int floor = (int) Math.floor(n / 2);
        return mypowcore(x, floor) * mypowcore(x, n - floor);
    }


    public double myPowSubProcessA(double x, int n) {
        if (n == 1) return x;
        if (n == 0) return 1;
        int floor = (int) Math.floor(n / 2);
        return myPowSubProcessA(x, floor) * myPowSubProcessA(x, n - floor);
    }
}
